import datetime
from typing import Optional

import sqlalchemy as sa
from sqlalchemy import BigInteger, Boolean, Enum, Float, String, func
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.application.user.enums import LangCode
from src.infrastructure.db.models import Base
from src.infrastructure.db.models.m2ms import proxies_users


class User(Base):
    __tablename__ = "user"
    __mapper_args__ = {"eager_defaults": True}

    id: Mapped[int] = mapped_column(primary_key=True)
    telegram_id: Mapped[int] = mapped_column(BigInteger, unique=True)
    username: Mapped[Optional[str]] = mapped_column(String(50))
    is_banned: Mapped[bool] = mapped_column(Boolean, server_default=sa.False_())
    is_registered: Mapped[bool] = mapped_column(Boolean, server_default=sa.False_())
    balance: Mapped[float] = mapped_column(Float, server_default=sa.False_())
    email: Mapped[Optional[str]] = mapped_column((String(100)))
    orders = relationship("Order", back_populates="user")
    proxies = relationship("Proxy", secondary=proxies_users, back_populates="users")
    allowed_ips = relationship("AllowedIP", back_populates="user")
    payments = relationship("Payment", back_populates="user")
    lang_code: Mapped[LangCode] = mapped_column(Enum(LangCode), server_default="ru")
    test_proxy_acquired: Mapped[Optional[datetime.datetime]]
    was_registered: Mapped[datetime.datetime] = mapped_column(server_default=func.now())

    def __str__(self):
        return str(self.telegram_id)

    def __repr__(self):
        return f"<TgUser №{self.id} {self.telegram_id}>"
